package com.tools.common.security.secret;

import com.tools.common.exception.InvalidOperationException;
import com.tools.common.io.CharsetEnum;
import com.tools.common.object.Note;

import javax.crypto.spec.SecretKeySpec;

/**
 * HmacSHA256 单向加密算法
 * */
@Note("HmacSHA256 单向加密算法")
public final class HmacSHA256Cypher implements OneWayCypher {

    @Note("加密对象")
    private final SecretKeySpec secretKeySpec;

    @Note("字符集")
    private final CharsetEnum charset;

    /* **************************************************************************************
     *
     *          构造器
     *
     * **************************************************************************************
     * */

    public HmacSHA256Cypher(SecretKeySpec secretKeySpec) {
        this(secretKeySpec, CharsetEnum.UTF_8);
    }

    public HmacSHA256Cypher(String secretKey) {
        this(secretKey, CharsetEnum.UTF_8);
    }

    public HmacSHA256Cypher(SecretKeySpec secretKeySpec, CharsetEnum charset) {
        this.private_checkSecretKeySpec(secretKeySpec);
        this.private_checkCharsetEnum(charset);
        this.secretKeySpec = secretKeySpec;
        this.charset = charset;
    }

    public HmacSHA256Cypher(String secretKey, CharsetEnum charset) {
        this.private_checkSecretKeySpec(secretKey);
        this.private_checkCharsetEnum(charset);
        this.secretKeySpec = SecretKit.newHmacSHA256SecretKeySpec(secretKey, charset);
        this.charset = charset;
    }

    /* **************************************************************************************
     *
     *          实现方法
     *
     * **************************************************************************************
     * */

    @Override
    public boolean isOneWay() {
        return true;
    }

    @Override
    public boolean isTwoWay() {
        return false;
    }

    @Override
    public String encrypt(String plaintext) {
        return SecretKit.encryptWithHmacSHA256(plaintext, this.secretKeySpec, this.charset);
    }

    @Override
    public String encrypt(String plaintext, CharsetEnum charset) {
        return SecretKit.encryptWithHmacSHA256(plaintext, this.secretKeySpec, charset);
    }

    @Override
    public String decrypt(String ciphertext) {
        throw new InvalidOperationException("HmacSHA256 哈希算法属于单向加密技术，无法解密");
    }

    @Override
    public String decrypt(String ciphertext, CharsetEnum charset) {
        throw new InvalidOperationException("HmacSHA256 哈希算法属于单向加密技术，无法解密");
    }

    /* **************************************************************************************
     *
     *          私有逻辑
     *
     * **************************************************************************************
     * */

    @Note("密钥对象的非空校验")
    private void private_checkSecretKeySpec(SecretKeySpec secretKey) {
        if(secretKey == null) {
            throw new NullPointerException("HmacSHA256 的密钥为 null");
        }
    }

    @Note("密钥对象的非空校验")
    private void private_checkSecretKeySpec(String secretKey) {
        if(secretKey == null) {
            throw new NullPointerException("HmacSHA256 的密钥为 null");
        }
    }

    @Note("校验字符集枚举")
    private void private_checkCharsetEnum(CharsetEnum charset) {
        if(charset == null) throw new NullPointerException("字符集枚举为 null");
    }
}
